package com.yyl.fmall.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yyl.fmall.order.entity.OrderItem;
import com.yyl.fmall.order.entity.Orders;
import com.yyl.fmall.order.mapper.OrdersMapper;
import com.yyl.fmall.order.service.IOrderItemService;
import com.yyl.fmall.order.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yyl.fmall.order.vo.AddOrderReturnVo;
import com.yyl.fmall.product.entity.Product;
import com.yyl.fmall.product.entity.ProductImg;
import com.yyl.fmall.product.entity.ProductSku;
import com.yyl.fmall.product.service.IProductImgService;
import com.yyl.fmall.product.service.IProductService;
import com.yyl.fmall.product.service.IProductSkuService;
import com.yyl.fmall.shopcart.entity.ShoppingCart;
import com.yyl.fmall.shopcart.service.IShoppingCartService;
import com.yyl.fmall.user.exception.IllegalCharacterException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单  服务实现类
 * </p>
 *
 * @author YuanSir
 * @since 2022-11-09
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {
    
    @Autowired
    private IShoppingCartService shoppingCartService;
    
    @Autowired
    private IOrderItemService orderItemService;
    
    @Autowired
    private IProductSkuService productSkuService;
    
    @Autowired
    private IProductService productService;
    
    @Autowired
    private IProductImgService productImgService;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized AddOrderReturnVo add(String cids, Orders orders) {
        
        //准备所需的数据结构
        List<String> cartIdList = Arrays.asList(cids.replaceAll("#", "").split(","));
    
        List<ShoppingCart> shoppingCartList = shoppingCartService.list(new LambdaQueryWrapper<ShoppingCart>()
                .in(ShoppingCart::getCartId, cartIdList));
    
        List<String> productIdList = shoppingCartList.stream()
                .map(ShoppingCart::getProductId)
                .distinct()
                .collect(Collectors.toList());
    
        Map<String, String> productIdNameMap = productService.list(new LambdaQueryWrapper<Product>()
                        .in(Product::getProductId, productIdList))
                .stream()
                .collect(Collectors.toMap(Product::getProductId, Product::getProductName));
    
        Map<String, String> productImgIdUrlMap = productImgService.list(new LambdaQueryWrapper<ProductImg>()
                        .eq(ProductImg::getIsMain, 1)
                        .in(ProductImg::getItemId, productIdList))
                .stream()
                .collect(Collectors.toMap(ProductImg::getItemId, ProductImg::getUrl));
    
        List<ProductSku> productSkuList = productSkuService.list(new LambdaQueryWrapper<ProductSku>()
                .in(ProductSku::getProductId, productIdList));
    
        //判断库存是否足够
        for (ProductSku productSku : productSkuList) {
    
            List<ShoppingCart> shoppingCarts = shoppingCartList.stream()
                    .filter(shoppingCart -> Objects.equals(shoppingCart.getProductId(), productSku.getProductId()))
                    .collect(Collectors.toList());
    
            for (ShoppingCart shoppingCart : shoppingCarts) {
    
                if (productSku.getStock() < Integer.parseInt(shoppingCart.getCartNum())){
        
                    throw new IllegalCharacterException("库存不足，请调整商品数量再进行下单！");
        
                } else {
    
                    productSku.setStock((productSku.getStock() - Integer.parseInt(shoppingCart.getCartNum())));
                    productSkuService.updateById(productSku);
                    
                }
                
            }
            
        }
        
        orders.setOrderId(UUID.randomUUID().toString().replaceAll("-",""));
    
        List<String> productSkuNameList = productSkuList.stream()
                .map(ProductSku::getSkuName)
                .collect(Collectors.toList());
        
        StringBuilder skuNamePlus = new StringBuilder();
        
        productSkuNameList.forEach(
                productSkuName -> skuNamePlus.append(productSkuName).append(",")
        );
        
        orders.setUntitled(skuNamePlus.toString());
        
        orders.setStatus("1");
        
        orders.setCreateTime(new Date());
        
        orders.setUpdateTime(new Date());
        
        shoppingCartService.populateShoppingCartList(shoppingCartList);
        
        shoppingCartList.forEach(
                
                shoppingCart -> {
                    OrderItem orderItem = new OrderItem();
    
                    BeanUtils.copyProperties(shoppingCart ,orderItem);
                    
                    orderItem.setItemId(UUID.randomUUID().toString().replaceAll("-",""));
                    
                    orderItem.setOrderId(orders.getOrderId());
                    
                    orderItem.setProductName(productIdNameMap.get(shoppingCart.getProductId()));
                    
                    orderItem.setProductImg(productImgIdUrlMap.get(shoppingCart.getProductId()));
                    
                    orderItem.setProductPrice(BigDecimal.valueOf(Long.valueOf(shoppingCart.getSellPrice())));
                    
                    orderItem.setBuyCounts(Integer.valueOf(shoppingCart.getCartNum()));
    
                    orderItem.setTotalAmount(BigDecimal.valueOf(Long.valueOf(shoppingCart.getSellPrice())));
                    
                    orderItem.setBasketDate(new Date());
                    
                    orderItemService.save(orderItem);
                    
                }
                
        );
        
        save(orders);
    
        shoppingCartService.remove(new LambdaQueryWrapper<ShoppingCart>()
                .in(ShoppingCart::getCartId, cartIdList));
    
        return new AddOrderReturnVo(orders.getOrderId(), orders.getUntitled(), "https://www.baidu.com/");
        
    }
    
    @Override
    public String status(String orderId) {
        return null;
    }
    
    @Override
    public void deleteExpiredOrders() {
    
    }
}
